import re


def extract_after_type(text):
    for type in ["判断题", "单选题", "多选题"]:
        if type in text:
            return text.split(type)[-1].lstrip("：:").strip()
    return text.strip()


def extract_question_rich(raw_text):
    """
    提取题干（从原始 OCR 文本中剔除选项部分，只保留题干）
    对于判断题，会统一在末尾追加 "N:错误Y:正确"
    """
    if not raw_text or not isinstance(raw_text, str):
        return ""

    text = raw_text.strip()
    text = extract_after_type(text)
    # 判断是否为判断题
    is_tf = '判断题' in raw_text

    # Step 1: 去掉题目前缀乱码 + 编号（如 剩余46S（判断题）11、）
    text = re.sub(r'^.*?[^\u4e00-\u9fa5]{0,5}[\d]{1,4}[、.，)]{1,2}', '', text)

    # Step 2: 移除 OCR 中已有的判断项，例如：
    text = re.sub(r'(N[:：]?[正确错误]{2}|Y[:：]?[正确错误]{2})+', '', text)

    # Step 3: 截断选择题的 A/B/C/D
    text = re.split(r'\s*[A-D][\.、:：]', text)[0]

    # Step 4: 清理无关内容
    text = re.sub(r'(交管12123|学法减分|交通安全|驾驶员|请选择正确的答案|下一题|剩余\d+s?)', '', text)
    text = re.sub(r'[A-Za-z]?\d{5,}[A-Za-z]?', '', text)

    # Step 5: 清理多余空格
    text = re.sub(r'\s+', ' ', text).strip()

    # Step 6: 判断题末尾添加判断选项
    if is_tf:
        text += " N:错误Y:正确"

    return text


def extract_ocr_options(text):
    """
    更鲁棒地从OCR原文中提取A/B/C/D选项内容。
    自动忽略题干部分，只处理选项内容。
    返回： (options_list, raw_pairs_list)
    """
    import re

    def _normalize(txt):
        return txt.strip(" ：:.\n")

    def _split_question_and_options(text):
        # 尝试先找 A
        match = re.search(r'A[:：\.、]?', text)
        if match:
            return text[:match.start()], text[match.start():]

        # 找不到 A，找 B 或 C 或 D
        match = re.search(r'[B-D](?=[^\sA-D:：\.、])', text)
        if match:
            return text[:match.start()], text[match.start():]

        return text, ''

    # 分离题干与选项部分
    question_text, option_text = _split_question_and_options(text)

    if not option_text:
        return [], []

    # 若A缺失，尝试用题干最后一句话作为A选项内容
    if not re.match(r'^A[:：\.、]', option_text):
        tail = re.findall(r'[^，。？！；\n]{4,}$', question_text)
        if tail:
            option_text = f"A:{tail[-1]}" + option_text

    # 统一冒号格式，去除重复冒号（如C:：）
    option_text = re.sub(r'([A-D])[:：]{1,}', r'\1:', option_text)

    # 补充标签和分隔符之间没空格或符号的情况，如 B准备抢行 → B:准备抢行
    option_text = re.sub(r'([A-D])(?=[^\sA-D:：\.、])', r'\1:', option_text)

    # 匹配选项部分，非贪婪
    pattern = r'([A-D]):(.*?)(?=([A-D]:)|$)'
    matches = re.findall(pattern, option_text)

    # 生成字典方便补全
    pair_dict = {}
    for label, content, _ in matches:
        pair_dict[label] = _normalize(content)

    # 保证返回的选项列表完整，有缺失用空字符串填充
    labels = ['A', 'B', 'C', 'D']
    options = []
    raw_pairs = []
    for label in labels:
        val = pair_dict.get(label, '')
        options.append(val)
        raw_pairs.append((label, val))

    return options, raw_pairs


def prepare_query_text(raw_text):
    """
    从OCR文本中提取题干和选项，
    对选项排序后拼接返回
    """
    # 提取题干
    subject = extract_question_rich(raw_text)
    # 提取选项
    _, ocr_options = extract_ocr_options(raw_text)
    options = [opt[1].strip() for opt in ocr_options if opt[1].strip()]
    options.sort()
    # 拼接题干 + 排序后的选项
    full_text = subject + ' ' + ' '.join(options)
    return full_text


texts = [
    "7:40返回学法减分考试2310121314151620剩余59S(多选题）18、驾驶车辆时在道路上抛撒物品，以下说法正确的是什么？A：有可能引起其他驾驶人紧急躲避等应激反应，进而引发事故B：为了保持车内整洁可以偶尔做出这种行为C：破坏环境，影响环境整洁，甚至造成路面的损坏D：抛撒纸张等轻质物品会阻挡驾驶人视线，分散驾驶人的注意力"
]

for t in texts:
    raw_pairs = prepare_query_text(t)
    print(":", raw_pairs)
    print()
